package cc.ufinity.networkdiagnose.manager;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

import android.util.Log;
/**
 * FTP测试类
 * @author ZR
 *
 */
public final class FtpTestManager extends AbstractManager {

	private static final int DEFAULT_CONNECT_TIMEOUT = 30 * 1000; 
	protected FTPClient ftpClient;
	private String localFilePath;
	private String remoteFilePath;
	private String fileName;
	private long fileSize;
	private long loginTime;
	public int failedTimes;
	/*
	private WlanManager wlanManager;
	private Activity ctx;*/

	private long startTime;
	private long endTime;
	private boolean isGotStartTime;
	private boolean isEnd = false;
	
	public long getLoginTime() {
		return loginTime;
	}

	public long getFileSize() {
		return fileSize;
	}

	public void setFileSize(long fileSize) {
		this.fileSize = fileSize;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	private int frequency = 0;// 测试频率

	private boolean testing;

	public boolean isTesting() {
		return testing;
	}

	public void setTesting(boolean testing) {
		this.testing = testing;
	}

	public int getFrequency() {
		return frequency;
	}

	public int currentTimes;// 当前测试次数

	public int getCurrentTimes() {
		return currentTimes;
	}

	private double[] upX = null;// 绘制上传报表X轴数据

	public double[] getUpX() {
		return upX;
	}

	private double[] upY = null;// 绘制上传报表Y轴数据

	public double[] getUpY() {
		return upY;
	}

	private double[] dwX = null;

	public double[] getDwX() {
		return dwX;
	}

	private double[] dwY = null;

	public double[] getDwY() {
		return dwY;
	}

	private float currentUpSpeed = 0; 
	private float currentDwSpeed = 0;
	private float totalDwSpeed = 0;
	private float totalUpSpeed = 0;

	public FtpTestManager(final String localFilePath,
			final String remoteFilePath, final String fileName) {
		this.fileName = fileName;  
		this.localFilePath = localFilePath;
		this.remoteFilePath = remoteFilePath;
		ftpClient = new FTPClient();
		ftpClient.setConnectTimeout(30 * 1000); // 半分钟，如果超过就判定超时了
	}


	public void startFtpUpTest(final int frequency) {
		this.frequency = frequency;
		upX = new double[frequency];
		upY = new double[frequency];

		
		while (currentTimes < frequency) { 
			// 进行上传测试
			if (!testing) {
				setTesting(true);
				System.out.println("---------  FTP上传开始。。。");
				currentUpSpeed = upload();
				System.out.println("---------  FTP上传结束。。。    " + currentUpSpeed + " KB/S");
				// setTestData();
				upX[currentTimes] = currentTimes;
				upY[currentTimes] = currentUpSpeed;
				this.setTotalUpSpeed(currentUpSpeed);
				currentTimes++;
				sendMsg(MessageWhat.FTP_UPLOAD_DONE);
			}
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) { }
		}
	}

	public void startFtpDwTest(final int frequency) {
		currentTimes = 0;
		setTesting(false);
		dwX = new double[frequency];
		dwY = new double[frequency];
		while (currentTimes < frequency) {
			// 进行下载测试
			if (!testing) {
				setTesting(true);
				System.out.println("---------  FTP下载开始。。。");
				currentDwSpeed = download();
				System.out.println("---------  FTP下载结束。。。    " + currentDwSpeed + " KB/S");
				// setTestData();
				dwX[currentTimes] = currentTimes;
				dwY[currentTimes] = currentDwSpeed;
				this.setTotalDwSpeed(currentDwSpeed);
				currentTimes++;
				// 一次轮询测试结束通知界面刷新数据
				sendMsg(MessageWhat.FTP_DOWNLOAD_DONE);
			}
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) { }
		}
		// 通知界面测试结束
		sendMsg(MessageWhat.DONE);
	}

	public void logout() {
		try {
			ftpClient.disconnect();
		} catch (IOException e) {
			Log.e("FTP Logout", "FTP退出认证出错：", e);
		}
	}

	public boolean login(final String address, final int port,
			final String user, final String pwd) {
		boolean result = false;
		try {
			long start = System.currentTimeMillis();
			ftpClient.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT);
			ftpClient.connect(address, port);
            System.out.println("----------- " + address);
			boolean loginResult = ftpClient.login(user, pwd);
			int returnCode = ftpClient.getReplyCode();
			if (loginResult && FTPReply.isPositiveCompletion(returnCode)) {
				initRemote();
				result = true;
				loginTime = System.currentTimeMillis() - start;
			}
		} catch (Exception e) {
			result = false;
			Log.e("FTP Login", "FTP登陆认证出错：", e);
		}
		return result;
	}

	private void initRemote() throws IOException {
		
		ftpClient.makeDirectory(remoteFilePath);
		ftpClient.changeWorkingDirectory(remoteFilePath);
//		ftpClient.changeWorkingDirectory("/");
		ftpClient.setBufferSize(1024);
		ftpClient.setControlEncoding("UTF-8");
		ftpClient.enterLocalPassiveMode();
		ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
		ftpClient.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT);
	}
	
	// FTP 上传文件测试
	public void upload(String fileName) {
	  /*if(NetworkManager.detectNetworkConnectivity(ctx) == -1)
		{
			return ;
		}*/
		
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(localFilePath + fileName);
			ftpClient.storeFile(fileName, fis);
		} catch (IOException e) {
			Log.e("FTP Upload", "FTP上传文件出错：", e);
		} finally {
			try {
				if (null != fis) {
					fis.close();
				}
			} catch (IOException e) {
				// ignore
			}
		}
	}
	class ftpTimerTask extends TimerTask {
		FileInputStream fis;
		Timer timer;
		public ftpTimerTask(FileInputStream fis, Timer timer) {
			this.fis = fis;
			this.timer = timer;
		}
		@Override
		public void run() {
			System.out.println("------ ftp上传超时");
			try {
				if (null != fis) {
					fis.close();
				}
				timer.cancel();
			} catch (IOException e) {
				System.out.println("------ ftp上传超时 -------");
			}
		}
	}
	
	// 单项FTP 上传文件测试
	private float upload2() {
		FileInputStream fis = null;
		float speed = 0;
		final Timer timer = new Timer(true);
        timer.schedule(new ftpTimerTask(fis, timer), 100, 3 * 1000);
		try {
			fis = new FileInputStream(localFilePath + fileName);
			long start = System.currentTimeMillis();
			fileSize = fis.available();
			boolean b = ftpClient.storeFile(fileName, fis);
			timer.cancel();
			if(b) {
				long time = System.currentTimeMillis() - start;
				speed = ((float) fileSize/1024)/((float)time/1000);
			} else {
				speed = 0;
			}
		} catch (IOException e) {
			Log.e("FTP Upload", "FTP上传文件出错：", e);
			return 0;
		} finally {
			try {
				if (null != fis) {
					fis.close();
				}
			} catch (IOException e) {
				Log.e("FTP Upload", "FTP上传输入流关闭出错：", e);
			}
		}
		return speed;
	}

	// FTP 上传文件测试
	public float upload() {
	 
		FileInputStream fis = null;
		float speed = 0;		 
		try {
			fis = new FileInputStream(localFilePath + fileName);
			long start = System.currentTimeMillis();
			fileSize = fis.available();
			System.err.println("FTP Upload------++++++1111111------FTP上传文件出错：");
			boolean b = ftpClient.storeFile(fileName, fis);
			System.err.println("FTP Upload-----55555555555+++++=-------FTP上传文件出错：");
			isEnd = true;
			if(b) {
				long time = System.currentTimeMillis() - start;
				try{
					speed = (((float) fileSize)/1024)/(((float)time)/1000);
				}catch(Exception e){
					System.err.println("FTP Upload----44444444445+++++=-------FTP上传文件出错：");
				}
			} else {
				speed = 0;
			}
			System.err.println("FTP Upload-----888888888888+++++=-------FTP上传文件出错：");
		} catch (IOException e) {
			 System.err.println("FTP UploadFTP上传文件出错：");
			Log.e("FTP Upload", "FTP上传文件出错：", e);
			return 0;
		} finally {
			try {
				if (null != fis) {
					fis.close();
					fis=null;
				}
			} catch (IOException e) {
				Log.e("FTP Upload", "FTP上传输入流关闭出错：", e);
				 System.err.println("FTP Upload------------FTP上传文件出错：");
			}
		}
		return speed;
	}

	// FTP下载测试
	public float download() {
		isGotStartTime = false;
//		fileName = "1.zip";
//		localFilePath = "/";
		File file = new File(localFilePath + fileName);
		if (file.exists()) {
			file.delete();
		}
		new Thread(){
			FileInputStream fis = null;
			int startFileSize = 0;
			int endFileSize = 0;
			public void run(){
				isEnd = false;
				while(!isEnd){
					try {
						if(fis == null) {
							fis = new FileInputStream(localFilePath + fileName);
						}
						endFileSize = fis.available();
						if(endFileSize > fileSize*0.2f) {
							if(!isGotStartTime) {
								isEnd = true;
								isGotStartTime = true;
								startTime = System.currentTimeMillis();
							}
						}
						/*System.out.println("------ FTP实时下载速度： " 
								+ (((float) (endFileSize-startFileSize))/1024)/0.1f);
						startFileSize = fis.available();
						Thread.sleep(10);*/
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				try {
					fis.close();
				} catch (Exception e) {}
			}
		}.start();
		float speed = 0;
		FileOutputStream fos = null;
		FileInputStream fis = null;
		try {
			fos = new FileOutputStream(file);
			long start = System.currentTimeMillis();
			ftpClient.retrieveFile(fileName, fos);
			isEnd = true;
			fis = new FileInputStream(localFilePath + fileName);
			long time = 1;
			if(isGotStartTime) {
				time = System.currentTimeMillis() - startTime;
			} else {
				time = System.currentTimeMillis() - start;
			}
			speed = (((float) 0.8*fis.available())/1024)/(((float)time)/1000);
		} catch (Exception e) {
			Log.e("FTP Download", "FTP下载测试出错：", e);
		} finally {
			try {
				if (null != fos) {
					fos.close();
				}
				if (null != fis) {
					fis.close();
				}
			} catch (IOException e1) {
				Log.e("FTP Download", "FTP下载输出流关闭出错：", e1);
			}
		}
		return speed;
	}

	public float getCurrentUpSpeed() {
		return currentUpSpeed;
	}

	public float getCurrentDwSpeed() {
		return currentDwSpeed;
	}

	public float getTotalUpSpeed() {
		return totalUpSpeed;
	}

	public void setTotalUpSpeed(float totalUpSpeed) {
		this.totalUpSpeed += totalUpSpeed;
	}

	public float getTotalDwSpeed() {
		return totalDwSpeed;
	}

	public void setTotalDwSpeed(float totalDwSpeed) {
		this.totalDwSpeed += totalDwSpeed;
	}

	/*public Activity getCtx() {
		return ctx;
	}

	public void setCtx(Activity ctx) {
		this.ctx = ctx;
	}*/

}
